home *** CD-ROM | disk | FTP | other *** search
- /**\
- |**| =====================================================================
- |**|
- |**| QDGX shell.c
- |**|
- |**| This file is a shell that can be used to build "new" Graphics
- |**| applications. It contains all of the required calls to use the "new"
- |**| Graphics routines and QuickDraw (i.e. windows) together. It can put up
- |**| one or more window. This shell also supports GX printing.
- |**|
- |**| The application is expected to supply the following functions which
- |**| are called by this shell:
- |**| void DoSetup (void);
- |**| void DoDraw (WindowPtr);
- |**| OSErr DoCreateNew (void);
- |**| void DoDispose (WindowPtr);
- |**| void DoIdle (WindowPtr);
- |**| void DoTeardown (void);
- |**| void DoClick (WindowPtr, Point);
- |**|
- |**|
- |**| Change History:
- |**| 3/90 New
- |**| 6/91 PLA Updated the shell to reflect the changes in
- |**| "Graphics" v1.0d21.2.
- |**| 6/92 Made the following variables global: gDebugging,
- |**| gGiveMeValidation,gGraphicsHeapSize.
- |**| See the comments for detail in this file.
- |**| 6/92 DMH Added printing guts, mangled and reorganized.
- |**| 9/93 PLA Updated files to work with the ß2 "GXified"
- |**| interface files.
- |**| 9/93 DMH Added override for gxPrintingEvent to handle
- |**| update events.
- |**| 9/93 DMH Added GXUpdateJob for resume events.
- |**| 12/93 MD Extensive changes made for clarity, shell-like
- |**| ability, cleanliness.
- |**| 8/94 DH More changes made for universal header and clarity
- |**|
- |**| ©1992-1994 Apple Computer, Inc.
- |**| All rights reserved.
- |**|
- |**| =====================================================================
- \**/
-
-
- #include "QDGX shell.h"
-
-
- /**\
- |**| ---------------------------------------------------------------------
- |**| GLOBALS
- |**| ---------------------------------------------------------------------
- \**/
- Boolean gQuitting = false;
- long gSleep = 0;
-
- #if defined(powerc) && !defined(__MWERKS__)
- QDGlobals qd;
- #endif
-
-
-
-
- /**\
- |**| ---------------------------------------------------------------------
- |**| main()
- |**| ---------------------------------------------------------------------
- \**/
- void main()
- {
- CursHandle theCurs;
- Handle menuBar;
- OSErr err;
- WindowPtr wind;
- gxGraphicsClient client;
-
- InitToolbox();
-
- theCurs = GetCursor(watchCursor);
- SetCursor(*theCurs);
-
- menuBar = GetNewMBar(rMenuBar); // Create the menu bar.
- SetMenuBar(menuBar);
- DisposeHandle(menuBar);
-
- CheckQuickDrawGX();
- if (gQuitting)
- {
- SetCursor(&qd.arrow);
- (void) StopAlert(rNoQuickDrawGXID, NULL);
- return;
- }
-
-
- // Before starting to draw, we'll call the DoSetup routine so we can initialize any
- // global variables or behaviors. This routine would be a good time to change the
- // gGraphicsHeapSize variable before we make the new graphics client next.
-
- DoSetup();
-
-
- // The GXNewGraphicsClient routine defines the graphics heap size. If you do not make this
- // call, the GX graphics engine will create this heap automatically. How? It will create
- // a heap which is a percentage of your application's ideal memory foot print. This call
- // allows you to explicity define the ammount of memory used by the graphics system for
- // its graphics objects heap.
-
- client = GXNewGraphicsClient(nil, gGraphicsHeapSize * 1024, 0L);
-
- if ( client )
- {
- // If gDebugging = TRUE, you will receive graphics library errors & notices will be posted.
- // This functionality will only work with the "debugging" version of QuickDraw GX. If you
- // don't have the debugging version installed, these functions will not work.
-
- if (gDebugging)
- {
- SetGraphicsLibraryErrors ();
- SetGraphicsLibraryNotices();
- }
-
- // Set gGiveMeValidation to TRUE if you want run-time validation. As you increase the amount
- // of validation, The drawing speed will SLOW down due to all of the internal checking.
-
- // gxPublicValidation will check parameters to public routines. For additional details
- // regarding the various levels of validation, see "Inside Macintosh: QuickDraw GX
- // Environment and Utilties."
-
- if (gGiveMeValidation)
- GXSetValidation(gxPublicValidation);
-
-
- // Initialize the new graphics and printing environments.
-
- if ( GXGetGraphicsError( nil ) != out_of_memory )
- {
- GXEnterGraphics();
- err = GXInitPrinting();
-
- // Initialize the other managers, if no errors occurred.
-
- if ( err == noErr )
- {
- gQuitting = false;
- AddResMenu(GetMHandle(mApple), 'DRVR'); // add Apple Menu items.
- DrawMenuBar();
-
- // We initialize the CommonColors Library. This will allow us to set the color of a
- // shape by calling the SetShapeCommonColor function. We will need to call
- // DisposeCommonColors when we leave, to clean up the world.
-
- InitCommonColors();
-
- DoCreateNew();
-
- SetCursor(&qd.arrow);
-
- while (!gQuitting)
- EventLoop();
-
- // Leaving. Close all the windows so we get rid of any data we or GX created. Then,
- // dispose of the common colors and exit the GX printing and graphics environment.
-
- while ( (wind = FrontWindow()) != NULL )
- DoDispose(wind);
-
- DisposeCommonColors();
- GXExitPrinting(); // Close the new printing mgr.
- }
-
- GXExitGraphics(); // Deallocate all of the default structures
-
- } else DebugStr ("\p Unfortunately, there is not enough memory for GX, please quit an app...");
- } else DebugStr ("\p Unfortunately, there is not enough memory for GX, please quit an app...");
-
- GXDisposeGraphicsClient(client);
- DoTeardown(); // Dispose of any global variables we made in DoSetup.
- }
-
-
- /**\
- |**| ---------------------------------------------------------------------
- |**| InitToolbox()
- |**| ---------------------------------------------------------------------
- \**/
- void InitToolbox (void)
- {
- // Generic heap initialization.
-
- MaxApplZone();
- MoreMasters(); MoreMasters(); MoreMasters();
- MoreMasters(); MoreMasters(); MoreMasters();
-
- // Start up the toolbox so we can notify people if there's a problem
-
- InitGraf(&qd.thePort);
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs(nil);
- InitCursor();
- }
-
-
- /**\
- |**| ---------------------------------------------------------------------
- |**| CheckQuickDrawGX()
- |**| Before making any calls, we'll see if QuickDraw GX is available.
- |**| If it's not, then set gQuitting=true so we can avoid doing any of
- |**| the rest of this application.
- |**| ---------------------------------------------------------------------
- \**/
- void CheckQuickDrawGX (void)
- {
- long theFeature;
-
- // Before making any calls, we'll see if QuickDraw GX is available. If it's not,
- // we'll avoid doing any of the rest of this application
-
- if ( (Gestalt(gestaltGraphicsVersion, &theFeature) != noErr) ||
- (Gestalt(gestaltGXPrintingMgrVersion, &theFeature) != noErr))
- gQuitting = true; // QuickDraw GX is not available
-
- #ifdef powerc
- // This is a sanity check to see if the PowerPC QuickDrawGXLib is installed.
- // Since we are "weak" linked to QuickDrawGXLib, the Process Manager will
- // launch us even if QuickDrawGXLib is missing. If it's missing, the
- // Code Fragment Manager will leave the address of the functions we call
- // unresolved, and we would crash if we tried to call that function. So,
- // we do a check here and should be prepared to exit gracefully if the
- // library is missing. This could happen if the user has installed a
- // 68K only version of QuickDraw GX. It could also happen if the user has
- // taken the QuickDraw GX extension out of the Extensions Folder.
- //
- // Note - We could check this against any function we call in the library.
- // GXNewGraphicsClient is the first function we call, so it's convenient.
-
- if ( (Ptr)GXNewGraphicsClient == kUnresolvedSymbolAddress )
- gQuitting = true; // QuickDraw GX is not available in Power Mac
- #endif
- }
-
-
- /**\
- |**| ---------------------------------------------------------------------
- |**| MyPrintingEventOverride()
- |**| Override for GXPrintingEvent. It allows us to update our windows
- |**| when the moveable modal printing dialogs are moved. Keep this in your
- |**| main segment, which will always be loaded when GX tries to call the routine.
- |**| ---------------------------------------------------------------------
- \**/
- OSErr MyPrintingEventOverride (EventRecord *event, Boolean filterEvent)
- {
- // Handle events in whatever way is appropriate.
- // MyDoEvent is our generic event handler.
-
- if ( !filterEvent )
- MyDoEvent(event);
- return noErr;
- }
-
-
- /**\
- |**| ---------------------------------------------------------------------
- |**| EventLoop()
- |**| ---------------------------------------------------------------------
- \**/
- void EventLoop ()
- {
- EventRecord event;
-
- if ( WaitNextEvent(everyEvent, &event, gSleep, nil) )
- MyDoEvent(&event);
- else
- DoIdle(FrontWindow());
- }
-
-
-
- /**\
- |**| ---------------------------------------------------------------------
- |**| IsAppWindow()
- |**| This routine looks to make sure a window pointer is not nil and that
- |**| the window it points to is of kind userKind. If it is, it returns
- |**| true, else it returns false.
- |**| ---------------------------------------------------------------------
- \**/
- Boolean IsAppWindow (WindowPtr wind)
- {
- return ((((WindowPeek) wind)->windowKind == userKind) && (wind != nil));
- }
-
-
- /**\
- |**| ---------------------------------------------------------------------
- |**| MyDoEvent()
- |**| ---------------------------------------------------------------------
- \**/
- void MyDoEvent (EventRecord *event)
- {
- char key;
- WindowPtr window; // temporarily used to hold
- GrafPtr oldPort;
- unsigned long mssg;
-
- mssg = event->message;
- switch(event->what)
- {
- case mouseDown:
- DoMouseDown(event);
- break;
-
- case keyDown:
- case autoKey:
- key = mssg & charCodeMask;
- if ( event->modifiers & cmdKey )
- if ( event->what == keyDown )
- DoMenuCommand(MenuKey(key));
- break;
-
- case updateEvt:
- window = (WindowPtr)mssg;
- if ( IsAppWindow(window) )
- {
- GetPort(&oldPort);
- SetPort(window);
- BeginUpdate(window);
- DoDraw(window, true);
- EndUpdate(window);
- SetPort(oldPort);
- }
- break;
-
- case activateEvt:
- break;
-
- case osEvt:
- if ( (mssg>>24) // if high byte of message indicates
- == suspendResumeMessage ) // this is suspend/resume event
- {
- if (mssg & resumeFlag) // if resume event
- { // we're switching back from another app so..
- gSleep = 0; // speed up
-
- // On a resume event, we need to call GXUpdateJob on all of our
- // documents' jobs. This is important because the user may have
- // just changed something which affects our jobs (like the size
- // of the paper in the printer).
- //
- // Since our application stores our document references in the refCon fields
- // of our documents' windows, we just loop through every one of our windows,
- // extract our document pointers and update the associated jobs.
-
- window = FrontWindow();
- while (window != nil)
- {
- if ( IsAppWindow(window) )
- GXUpdateJob(GetDocJob(window));
- window = (WindowPtr) ((WindowPeek) window)->nextWindow;
- }
- }
- else // if suspend event
- gSleep=80; // we're switching to another app so slow down...
- }
- break;
- }
- }
-
-
- /**\
- |**| ---------------------------------------------------------------------
- |**| DoMouseDown
- |**| handle DoMouseDown events
- |**| ---------------------------------------------------------------------
- \**/
- void DoMouseDown (EventRecord *event)
- {
- WindowPtr window;
- short clickArea;
- Rect screenRect;
-
- clickArea = FindWindow( event->where, &window );
- switch (clickArea)
- {
- case inSysWindow:
- SystemClick(event, window);
- break;
-
- case inDrag:
- screenRect = (**GetGrayRgn()).rgnBBox;
- if ( IsAppWindow(window) )
- DragWindow( window, event->where, &screenRect );
- break;
-
- case inContent:
- if (IsAppWindow(window))
- {
- if ( window == FrontWindow())
- DoClick(window, event->where);
- else
- SelectWindow(window);
- }
- break;
-
- case inGoAway:
- if ( IsAppWindow(window) )
- {
- if ( TrackGoAway(window, event->where) )
- DoDispose(window);
- }
- break;
-
- case inMenuBar:
- DoMenuCommand(MenuSelect(event->where));
- break;
-
- }
- }
-